"""
Case Type   : 基础功能-兼容B库语法-optimize
Case Name   : 使用多线程并发optimize不同表
Create At   : 2024/10/28
Owner       : peilinqian
Description :
        1.创建多个表,并插入数据
        2.使用多进程并发执行optimize3个表
        3.使用多进程并发执行optimize5个表
Expect      :
        1.创建表成功
        2.并发执行optimize3个表成功
        3.并发执行optimize5个表失败
History     :
"""

import os
import unittest

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class CompatibilityTest(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)}:初始化----')
        self.pri_sh = CommonSH('PrimaryDbBmode')
        self.constant = Constant()
        self.com = Common()
        self.tb_name = 't_compatibility_optimize_0008'

    def test_uuid_not_repeat(self):
        self.init_para = self.com.show_param("enable_defer_calculate_snapshot")
        step_txt = '----step1:创建表; expect:成功----'
        self.log.info(step_txt)
        create_msgs = []
        for i in range(10):
            sql = f'create table {self.tb_name + str(i)}(id text,name text);' \
                  f'insert into {self.tb_name + str(i)} ' \
                  f'values(generate_series(1,100000),\'a\');' \
                  f'delete from {self.tb_name + str(i)} where ' \
                  f'id>200 and id<50000;' \
                  f'delete from {self.tb_name + str(i)} where ' \
                  f'id>50005 and id<95000;'
            self.log.info(sql)
            res = self.pri_sh.execut_db_sql(sql)
            self.log.info(res)
            create_msgs.append(res)
        self.assertIn('CREATE TABLE\nINSERT 0 100000\nDELETE 49799\n'
                      'DELETE 44994', set(create_msgs), '执行失败:' + step_txt)
        self.assertEqual(len(set(create_msgs)), 1, '执行失败:' + step_txt)

        step_txt = '----step2:设置enable_defer_calculate_snapshot为off ' \
                   'expect:成功---'
        self.log.info(step_txt)
        sql = f'alter system set enable_defer_calculate_snapshot = off;' \
              f'select pg_sleep(2);'
        result = self.pri_sh.execut_db_sql(sql)
        self.log.info(result)
        self.assertIn(self.constant.alter_system_success_msg, result,
                      '执行失败:' + step_txt)

        step_txt = '----step3:三个并发执行optimize不同表; expect:成功----'
        self.log.info(step_txt)
        optimize_thread = []
        for j in range(3):
            insertcmd = f'optimize table {self.tb_name + str(j)}'
            optimize_thread.append(ComThread(self.pri_sh.execut_db_sql,
                                             args=(insertcmd,)))
            optimize_thread[j].setDaemon(True)
            optimize_thread[j].start()
        for j in range(3):
            optimize_thread[j].join(60)
            result = optimize_thread[j].get_result()
            self.log.info(result)
            self.assertIn(self.constant.VACUUM_SUCCESS_MSG, result,
                          '执行失败:' + step_txt)

        step_txt = '----step4:十个并发执行optimize不同表; expect:正常----'
        self.log.info(step_txt)
        optimize_thread = []
        for j in range(10):
            insertcmd = f'optimize table {self.tb_name + str(j)}'
            optimize_thread.append(ComThread(self.pri_sh.execut_db_sql,
                                             args=(insertcmd,)))
            optimize_thread[j].setDaemon(True)
            optimize_thread[j].start()
        for j in range(10):
            optimize_thread[j].join(60)
            result = optimize_thread[j].get_result()
            self.log.info(result)
            self.assertIn(self.constant.VACUUM_SUCCESS_MSG, result,
                          '执行失败:' + step_txt)

    def tearDown(self):
        step5_txt = '----step5:还原enable_defer_calculate_snapshot ' \
                    'expect:成功---'
        self.log.info(step5_txt)
        sql = f'alter system set enable_defer_calculate_snapshot=' \
              f'{self.init_para};'
        alter_result = self.pri_sh.execut_db_sql(sql)
        self.log.info(alter_result)

        step6_txt = '----step6:删除表; expect:成功----'
        self.log.info(step6_txt)
        drop_msgs = []
        for i in range(10):
            drop_cmd = f'drop table {self.tb_name + str(i)};'
            drop_msg = self.pri_sh.execut_db_sql(drop_cmd)
            self.log.info(drop_msg)
            drop_msgs.append(drop_msg)

        self.assertIn(self.constant.alter_system_success_msg, alter_result,
                      '执行失败:' + step5_txt)
        self.assertIn(self.constant.DROP_TABLE_SUCCESS, set(drop_msgs),
                      '执行失败:' + step6_txt)
        self.assertEqual(len(set(drop_msgs)), 1, '执行失败:' + step6_txt)
        self.log.info(f'----{os.path.basename(__file__)}:执行完毕----')
